package dao.impl;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import util.DBUtils;
import dao.BaseDao;

public abstract class BaseDaoImpl<T> implements BaseDao<T>{
	
//	protected Logger logger = LogManager.getLogger(this.getClass());
	
	protected Class<T> clazz;
	
	protected List<T> executeQuery(String sql,Object... object) throws Exception {
		String[] sqllist = sql.split("\\s+");
		List<String> pasql = new ArrayList<String>();
		Map<String, Class> map = new HashMap<>();
		for (int i = 0; i < sqllist.length; i++) {
			if (sqllist[i].contains("?")) {
				String[] paraStrings = sqllist[i].split("=");
				if (paraStrings.length!=2) {
					throw new Exception("unable to match:"+sqllist[i]);
				}
				pasql.add(paraStrings[0]);
				
			}
		}
		
		Connection conn = DBUtils.createConnection();
		PreparedStatement pst = null;
		pst = conn.prepareStatement(sql);
		
		Field[] fields = clazz.getDeclaredFields();
		for (int i = 0; i < fields.length; i++) {
			map.put(fields[i].getName(), fields[i].getType());
		}
		
		//设置参数
		Class clazzPst = pst.getClass();
		for (int i = 0; i < pasql.size(); i++) {
			Class paType =  map.get(pasql.get(i));
			String type = paType.getSimpleName();
			String methodName = "set"+type;
			System.out.println(methodName);
			Method method = clazzPst.getDeclaredMethod(methodName,Integer.TYPE,fields[i].getType());
			method.invoke(pst, i+1,paType.cast(object[i]));
		}
		
		ResultSet rs = pst.executeQuery();
			
			//组装pojo
			Class clazzRs = rs.getClass();
			List<T> lists = new ArrayList<>();
		while(rs.next()){
			T t = clazz.newInstance();
			for (int i = 0; i < fields.length; i++) {
				String fieldName = fields[i].getName();
				String setMethodName = "set"+fieldName.substring(0, 1).toUpperCase()+fieldName.substring(1);
				System.out.println(setMethodName);
				Method fileMethod = clazz.getDeclaredMethod(setMethodName,fields[i].getType());
				
				
				Method rsGetMethod = clazzRs.getDeclaredMethod("get"+fields[i].getType().getSimpleName(),String.class);
				
				fileMethod.invoke(t,rsGetMethod.invoke(rs, fieldName));
				
			}
			lists.add(t);
		}
		
		return lists;
		
		
		
	}
	
	public int executeUpdate(String sql,Object... object){
		return 0;
		
	}
	

}
